<?php
final class MySQL {
	private $connection;
	
	public function __construct($hostname, $username, $password, $database) {
		if (!$this->connection = mysql_connect($hostname, $username, $password)) {
      		exit('Error: Could not make a database connection using ' . $username . '@' . $hostname);
    	}

    	if (!mysql_select_db($database, $this->connection)) {
      		exit('Error: Could not connect to database ' . $database);
    	}
		
		mysql_query("SET NAMES 'utf8'", $this->connection);
		mysql_query("SET CHARACTER SET utf8", $this->connection);
		mysql_query("SET CHARACTER_SET_CONNECTION=utf8", $this->connection);
		mysql_query("SET SQL_MODE = ''", $this->connection);
  	}
		
  	public function query($sql) {
		$resource = mysql_query($sql, $this->connection);

		if ($resource) {
			if (is_resource($resource)) {
				$i = 0;
    	
				$data = array();
		
				while ($result = mysql_fetch_assoc($resource)) {
					$data[$i] = $result;
    	
					$i++;
				}
				
				mysql_free_result($resource);
				
				$query = new stdClass();
				$query->row = isset($data[0]) ? $data[0] : array();
				$query->rows = $data;
				$query->num_rows = $i;
				
				unset($data);

				return $query;	
    		} else {
				return TRUE;
			}
		} else {
      		exit('Error: ' . mysql_error($this->connection) . '<br />Error No: ' . mysql_errno($this->connection) . '<br />' . $sql);
    	}
  	}
	
	public function escape($value) {
		return mysql_real_escape_string((string)$value, $this->connection);
	}
	
  	public function countAffected() {
    	return mysql_affected_rows($this->connection);
  	}

  	public function getLastId() {
    	return mysql_insert_id($this->connection);
  	}	
	
	public function __destruct() {
		mysql_close($this->connection);
	}
	/**
     * Inserts one item into a table
     *
     * @param string $table The name of the table
     * @param array $items Array of fields to insert (if some is not specified the default value is assumed)
     * @return int The new ID of the item
     */
    public function insertTableRow($table, $items) {
        $this->fixQuotes($items);
        $fields = $this->getTableFieldsInfo($table);
 
        $query = "INSERT INTO `$table` (";
        foreach ($fields as $info){
            $query .= '`'.$info->name.'`, ';
		}
        $query = trim($query, ', ');
        $query .= ") VALUES(";
 
        foreach ($fields as $info) {
 
            if (isset($items[$info->name])) {
                if (strtoupper($items[$info->name]) == "NULL")
                    $val = "NULL, ";
                else
                    $val = "'".$this->escape($items[$info->name])."', ";
            }else{
                $val = "'".@$items[$info->def]."', ";
			}
 
            $query .= $val;
        }
 
        $query = trim($query, ', ');
        $query .= ")";
 
        //print $query;
        $r = mysql_query($query,$this->connection);
 
        return mysql_insert_id();
    }
 
    /**
     * Updates a table
     *
     * @param string $table The name of the table
     * @param int $id The ID of the row to update
     * @param array $items Array of new values ($items['columnName']['value'])
     * @return TRUE on success or FALSE on error
     */
    public function updateTableRow($table, $id, $items) {
        $this->fixQuotes($items);
        $fields = $this->getTableFieldsInfo($table);
 //dump($fields);
        $query = "UPDATE `$table` SET ";
        foreach ($fields as $info) {
            if (isset($items[$info->name])) {
                if ($items[$info->name] == 'NULL')
                    $query .= "`".$info->name."` = NULL, ";
                else
                    $query .= "`".$info->name."` = '".$this->escape($items[$info->name])."', ";
            }
        }
        $query = trim($query, ', ');
        $query .= " WHERE ".$items['primary']."='$id'";
        $r = mysql_query($query,$this->connection);
        //print $query;
 
        return $r;
    }
 
    //----------------------------------- PROTECTED -----------------------------------//
    /**
     * Returns an object containing all the fields info of a table
     *
     * @param strin $table The name of the table
     * @return object The fields info as an array of objects like:
     *      blob:         $fieldInfo->blob
     *      max_length:   $fieldInfo->max_length
     *      multiple_key: $fieldInfo->multiple_key
     *      name:         $fieldInfo->name
     *      not_null:     $fieldInfo->not_null
     *      numeric:      $fieldInfo->numeric
     *      primary_key:  $fieldInfo->primary_key
     *      table:        $fieldInfo->table
     *      type:         $fieldInfo->type
     *      default:      $fieldInfo->def
     *      unique_key:   $fieldInfo->unique_key
     *      unsigned:     $fieldInfo->unsigned
     *      zerofill:     $fieldInfo->zerofill
     */
    protected function getTableFieldsInfo($table) {
        $query = "SELECT * FROM `$table`";
        $result = mysql_query($query,$this->connection);
        while ($meta = mysql_fetch_field($result)) {
            if ($meta)
                $fieldInfo[] = $meta;
        }
        mysql_free_result($result);
        return $fieldInfo;
    }
 
    /**
     * Fixes single quotes in a string (or array of strings) to store it into the DB without error
     * @param mixed $str The string or array of strings to fix (by reference)
     */
    protected function fixQuotes(&$str) {
        if (is_array($str)) {
            foreach ($str as $key=>$text)
                $str[$key] = str_replace("'", "''", $text);
        }else{
            $str = str_replace("'", "''", $str);
		}
    }
}
?>